package com.wiloon.java8x.io.nio;
/*
 * Created by roy.wang on 2017/4/20;
 */

import com.wiloon.java8x.basic.Java8xUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;

public class IOWorkerTest {
    private static Logger logger = LoggerFactory.getLogger(IOWorkerTest.class);

    public static void main(String[] args) {
        new Thread(new IOWorker()).start();
        Java8xUtils.pid();
    }

    private static class IOWorker implements Runnable {
        public void run() {
            try {
                Selector selector = Selector.open();
                ServerSocketChannel channel = ServerSocketChannel.open();
                channel.configureBlocking(false);
                ServerSocket socket = channel.socket();
                socket.bind(new InetSocketAddress("localhost", 9000));
                logger.info("bind to port:9000");
                channel.register(selector, channel.validOps());
                while (true) {
                    logger.info("selecting...");
                    selector.select();
                    Iterator iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                        SelectionKey key = (SelectionKey) iterator.next();
                        logger.info("key:{},is valid:{},is acceptable:{}, is writable:{}", key, key.isValid(), key.isAcceptable(), key.isWritable());
                        iterator.remove();
                        if (!key.isValid()) {
                            continue;
                        }
                        if (key.isAcceptable()) {
                            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                            SocketChannel sc = ssc.accept();
                            sc.configureBlocking(false);
                            sc.register(selector, sc.validOps());
                        }
                        if (key.isWritable()) {
                            SocketChannel client = (SocketChannel) key.channel();
                            logger.info("channel:{}", client);
                            Charset charset = Charset.forName("UTF-8");
                            CharsetEncoder encoder = charset.newEncoder();
                            CharBuffer charBuffer = CharBuffer.allocate(32);
                            charBuffer.put("foo");
                            charBuffer.flip();
                            ByteBuffer content = encoder.encode(charBuffer);
                            client.write(content);
                            logger.info("channel write.");
                            key.cancel();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}